package org.anderground.app;

import static org.anderground.core.Logger.i;
import static org.anderground.core.Logger.w;

import org.anderground.app.activity.map.MetroMapActivity;
import org.anderground.app.controller.algorithms.MetroRouter;
import org.anderground.app.controller.algorithms.Route;
import org.anderground.app.model.AppModel;
import org.anderground.app.storage.global.StorageSetupActivity;
import org.anderground.core.model.ModelData;
import org.anderground.core.model.Station;
import org.anderground.core.storage.StorageException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

/**
 * @author Eldar Abusalimov
 */
public class MainActivity extends Activity {

	private static final int REQUEST_METRO_MAP_ACTIVITY = 0x1;

	/**
	 * Called when the activity is first created.
	 * 
	 * @param icicle
	 */
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		i("onCreate(Bundle icicle)");
new StorageException("",null);
		if (!StorageSetupActivity.ensureSetup(this)) {
			return;
		}

		new LoadModelTask(2).execute();

		Intent intent = new Intent(this, MetroMapActivity.class);
		startActivityForResult(intent, REQUEST_METRO_MAP_ACTIVITY);
		finish();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case REQUEST_METRO_MAP_ACTIVITY:
			i("onActivityResult REQUEST_METRO_MAP_ACTIVITY");
			break;

		default:
			break;
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		i("onSaveInstanceState(Bundle outState)");
		super.onSaveInstanceState(outState);
	}

	@Override
	protected void onPostCreate(Bundle icicle) {
		i("onPostCreate(Bundle icicle)");
		super.onPostCreate(icicle);
	}

	@Override
	protected void onStart() {
		i("onStart()");
		super.onStart();
	}

	@Override
	protected void onRestart() {
		i("onRestart()");
		super.onRestart();
	}

	@Override
	protected void onResume() {
		i("onResume()");
		super.onResume();
	}

	@Override
	protected void onPause() {
		i("onPause()");
		super.onPause();
	}

	@Override
	protected void onStop() {
		i("onStop()");
		super.onStop();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		i("onDestroy()");
	}

	private static final int OPEN_FILE_MENU_ITEM = Menu.FIRST;

	private static final int SETTINGS_MENU_ITEM = Menu.FIRST + 2;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, OPEN_FILE_MENU_ITEM, 0, "Open new map").setIcon(
				R.drawable.openmap);
		menu.add(0, SETTINGS_MENU_ITEM, 0, "Settings").setIcon(
				R.drawable.matmex);
		return true;
	}

	private static final int ID_ABOUT_DIALOG = 0x1;
	private static final int ID_MAP_INFO_DIALOG = 0x2;

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog = null;

		switch (id) {
		case ID_ABOUT_DIALOG:
			AlertDialog.Builder builder;
			builder = new AlertDialog.Builder(this);
			builder.setTitle(R.string.about_title);
			builder.setIcon(R.drawable.matmex_small);
			builder.setView(getLayoutInflater().inflate(R.layout.about, null));
			builder.setPositiveButton("Hide", new OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
				}
			});
			builder.setNegativeButton("Map info", new OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					showDialog(ID_MAP_INFO_DIALOG);
				}
			});
			dialog = builder.create();
			break;

		case ID_MAP_INFO_DIALOG:
			dialog = new MapInfoDialog(this);
			break;

		default:
			break;
		}

		return dialog;
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
		case ID_ABOUT_DIALOG:
			break;
		case ID_MAP_INFO_DIALOG:
			ModelData modelData = AppModel.getInstance().getData();
			((MapInfoDialog) dialog).prepare(modelData);
			break;

		default:
			break;
		}

		super.onPrepareDialog(id, dialog);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case OPEN_FILE_MENU_ITEM:
			// this.view.onOpenFileMenuItemSelected();
			return true;
		case SETTINGS_MENU_ITEM:
			showDialog(ID_ABOUT_DIALOG);
			// this.view.onSettingsMenuItemSelected();
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
	 * 
	 */
	private class LoadModelTask extends UserTask<Void, Void, ModelData> {

		private int cityId;

		/**
		 * load a new model data for the specified city
		 * 
		 * @param cityId
		 *            the city id
		 */
		public LoadModelTask(int cityId) {
			this.cityId = cityId;
		}

		@Override
		protected void onPreExecute() {
		}

		@Override
		protected void onPostExecute(ModelData result) {
			AppModel.getInstance().notifyObservers();
		}

		@Override
		protected void onFailure(FailureException reason) {
			w("model loading failed with an exception", reason.getCause());
		}

		@Override
		protected ModelData doInBackground(Void... voids)
				throws FailureException {
			try {
				return AppModel.getInstance().load(MainActivity.this, cityId);
			} catch (Throwable e) {
				throw new UserTask.FailureException(e);
			}
		}

	}

	private class PrepareRouterTask extends UserTask<Station, Void, Void> {

		@Override
		protected Void doInBackground(Station... params)
				throws UserTask.FailureException {
			MetroRouter.getInstance().prepare(params[0]);
			return null;
		}

	}

	private class SearchRoutesTask extends UserTask<Station, Void, Route[]> {

		@Override
		protected void onPostExecute(Route[] result) {
		}

		@Override
		protected Route[] doInBackground(Station... params)
				throws org.anderground.app.UserTask.FailureException {
			MetroRouter.getInstance().searchRoutes(params[0], params[1]);
			return null;
		}

	}

}
